package robot

import (
	"sync"
	"unsafe"
	"net"
)

// #include "export.h"
// #include <stdlib.h>
import "C"

var robots map[int]*robot
var mutex sync.Mutex
var exit bool

type robot struct {
	_id 			int
	_cpointer	unsafe.Pointer	
	_conn		*net.TCPConn
	_ch			chan int
}

const (
	ERROR = 0
	DEBUG = ERROR + 1
	INFO = DEBUG + 1
)

func CreateRobot(id int, ch chan int) bool {
	
	mutex.Lock()
	if robots == nil {
		robots = make(map[int]*robot)
	}
	_, ok := robots[id]
	if ok {
		return false
	}

	r := &robot{_id: id, _ch: ch}	
	if C.createRobot(C.uint(id)) != 0 {
		return false
	}

	robots[id] = r
	mutex.Unlock()

	m := C.CString("create")
	goLog(DEBUG, C.uint(id), m)	
	C.free(unsafe.Pointer(m))

	go r.run()
	return true
}

func DeleteRobot(id int) bool {

	mutex.Lock()
	delete(robots, id)
	C.removeRobot(C.uint(id))
	mutex.Unlock()

	m := C.CString("delete")
	goLog(DEBUG, C.uint(id), m)	
	C.free(unsafe.Pointer(m))

	return len(robots) == 0
}

func ExitRobot() {
	exit = true
}

func CanExit() bool {
	return exit
}

func Init() {
	C.initRobot()
}

func Destroy() {
	C.destroyRobot()
}

func (r *robot) run() {

	m := C.CString("start")
	goLog(DEBUG, C.uint(r._id), m)	
	C.free(unsafe.Pointer(m))

	C.runRobot(C.uint(r._id))

	m = C.CString("stop")
	goLog(DEBUG, C.uint(r._id), m)	
	C.free(unsafe.Pointer(m))

	r._ch <- r._id
}
